package com.gdc.cloud.config;

import com.gdc.myrule.MySelfRule_Advanced;
import com.netflix.loadbalancer.IRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

/**
 * Description: Config 配置类
 * @author: gdc
 * @date: 2021/1/31
 * @version 1.0
 */
@Configuration
public class ApplicationContextConfig {

    /**
     * 注入 RestTemplate
     *
     * | @LoadBalanced      使 RestTemplate 具有了客户端负载均衡能力
     *      作用： 使用了这个注解以后 ，会在  restTemplate 里面 通过 restTemplate.setInterceptors 放入  LoadBalancerInterceptor ，
     *          这个过滤器会在 请求远程成接口的时候 动态判断请求的域是不是  负载 负载均衡支付的服务的地址，如果是，那么就会代理 使用 这个负载均衡器 来调用。
     */
    @LoadBalanced
    @Bean
    public RestTemplate getRestTemplate(){
        return new RestTemplate();
    }

    /**
     * 修改 Balance 负载规则
     * Ribbon中的7中负载均衡算法：
     *
     * （1）RoundRobinRule：                   轮询；
     * （2）RandomRule：                       随机；
     * （3）AvailabilityFilteringRule：        先过滤掉故障实例，再选择并发较小的实例；
     * （4）WeightedResponseTimeRule：         根据平均响应时间计算所有服务的权重，响应时间越快的服务权重越大被选中的概率越大。
     *                                            刚启动时如果统计信息不足，则使用RoundRobinRule（轮询）策略，等统计信息足够，会切换到WeightedResponseTimeRule；
     * （5）RetryRule：                        先按照RoundRobinRule的策略获取服务，如果获取服务失败则再指定时间内重试，获取可用服务；
     * （6）BestAvailableRule：                先过滤掉由于多次访问故障而处于断路器跳闸状态的服务，然后选择一个并发量最小的服务；
     * （7）ZoneAvoidanceRule：                复合判断Server所在区域的性能和Server的可用性选择服务器；
     *
     */
    @Bean
    public IRule myRule(){
        //return new RoundRobinRule();
        //return new RandomRule();
        //return new AvailabilityFilteringRule();
        //return new WeightedResponseTimeRule();
        //return new RetryRule();
        //return new BestAvailableRule();
        //return new ZoneAvoidanceRule();
        return new MySelfRule_Advanced();
    }

}
